<?php
namespace app\controllers;

use yii\db\Query;
use yii\helpers\Url;
use yii\web\Controller;
use Yii;

class TrunkController extends BaseController
{

    /**
     * 中继列表
     * @return string|\yii\web\Response
     */
    public function actionIndex()
    {
        if (Yii::$app->request->isAjax){
            $db = (new Query())->select(['trunkid','name','outcid','channelid','maxchans','dialoutprefix'])
                ->from('trunks')
                ->orderBy('trunkid desc');
            $count = $db->count('trunkid',$this->asterisk_db);
            $page = Yii::$app->request->get('page',1);
            $limit = Yii::$app->request->get('limit',10);
            $data = $db->offset(($page-1)*$limit)->limit($limit)->all($this->asterisk_db);
            foreach ($data as &$d){
                $d['peer'] = '';
                $peer = (new Query())->from('sip')->where(['id'=>'tr-peer-'.$d['trunkid']])->andWhere(['!=','keyword','account'])->orderBy('flags asc')->all($this->asterisk_db);
                foreach ($peer as $p){
                    $d['peer'] .= $p['keyword']."=".$p['data']." | ";
                }
                $reg = (new Query())->from('sip')->where(['id'=>'tr-reg-'.$d['trunkid']])->one($this->asterisk_db);
                $d['reg'] = $reg['data'];
                $d['edit_url'] = Url::to(['edit','trunkid'=>$d['trunkid']]);
                $d['destroy_url'] = Url::to(['destroy','trunkid'=>$d['trunkid']]);
            }
            return $this->asJson([
                'code' => 0,
                'msg' => '请求成功',
                'count' => $count,
                'data' => $data
            ]);
        }
        return $this->render('index');
    }


    /**
     * 添加中继
     * @return string|\yii\web\Response
     */
    public function actionCreate()
    {
        $peer = <<<PEER
allowguest=yes
directmedia=no
dtmfmode=rfc2833
allow=g729&ulaw&alaw
qualify=20000
disallow=all
insecure=port,invite
port=5060
type=peer
host=xxx.xxx.xxx.xxx
username=xxxxxx
secret=xxxxxx
PEER;
        if (Yii::$app->request->isPost){
            $data = Yii::$app->request->post();
            //获取trunkid：trunks表里的trunkid不是自增的，这是一个坑
            $trunkid = (new Query())->from('trunks')->max('trunkid',$this->asterisk_db);
            $trunkid++;

            $transaction = $this->asterisk_db->beginTransaction();
            try{
                //写入trunks表
                $this->asterisk_db->createCommand()->insert('trunks',[
                    'trunkid' => $trunkid,
                    'tech' => 'sip',
                    'keepcid' => 'off',
                    'disabled' => 'off',
                    'continue' => 'off',
                    'name' => $data['name'],
                    'outcid' => $data['outcid'],
                    'maxchans' => $data['maxchans'],
                    'dialoutprefix' => $data['dialoutprefix'],
                    'channelid' => $data['channelid'],
                ])->execute();
                //写入sip表
                if (trim($data['peer'])){
                    $peers = explode("\n",trim($data['peer']));
                    $flags = 2;
                    $peerData[0] = ['tr-peer-'.$trunkid,'account',$data['channelid'],$flags];
                    foreach ($peers as $p){
                        ++$flags;
                        $item = explode("=",trim($p));
                        array_push($peerData,['tr-peer-'.$trunkid,$item[0],$item[1],$flags]);
                    }
                    $this->asterisk_db->createCommand()->batchInsert('sip',['id','keyword','data','flags'],$peerData)->execute();
                }
                if (trim($data['reg'])){
                    $this->asterisk_db->createCommand()->insert('sip',[
                        'id'        => 'tr-reg-'.$trunkid,
                        'keyword'   => 'register',
                        'data'      => trim($data['reg']),
                        'flags'     => 0
                    ])->execute();
                }
                //写入trunk_dialpatterns表
                if (!empty($data['dialpatterns'])){
                    $patternsData = [];
                    foreach ($data['dialpatterns'] as $key=>$d){
                        array_push($patternsData,[$trunkid,$d['match_pattern_prefix'],$d['match_pattern_pass'],$d['prepend_digits'],$key]);
                    }
                    $this->asterisk_db->createCommand()->batchInsert('trunk_dialpatterns',['trunkid','match_pattern_prefix','match_pattern_pass','prepend_digits','seq'],$patternsData)->execute();
                }
                $transaction->commit();
                //必需在提交事务后才重启
                $this->reload();
                return $this->asJson(['code'=>0,'msg'=>'添加中继成功']);
            }catch (\Exception $exception){
                $transaction->rollBack();
                return $this->asJson(['code'=>1,'msg'=>'添加中继失败','data'=>$exception->getMessage()]);
            }
        }
        return $this->render('create',['peer'=>$peer]);
    }

    public function actionEdit()
    {
        $trunkid = Yii::$app->request->get('trunkid');
        if (Yii::$app->request->isPost){
            $data = Yii::$app->request->post();
            $transaction = $this->asterisk_db->beginTransaction();
            try{
                //更新trunks表
                $this->asterisk_db->createCommand()->update('trunks',[
                    'tech' => 'sip',
                    'keepcid' => 'off',
                    'disabled' => 'off',
                    'continue' => 'off',
                    'name' => $data['name'],
                    'outcid' => $data['outcid'],
                    'maxchans' => $data['maxchans'],
                    'dialoutprefix' => $data['dialoutprefix'],
                    'channelid' => $data['channelid'],
                ],['trunkid' => $trunkid])->execute();
                //更新sip表peer,删除后再批量写入
                $this->asterisk_db->createCommand()->delete('sip',['id'=>'tr-peer-'.$trunkid])->execute();
                if (trim($data['peer'])){
                    $peers = explode("\n",trim($data['peer']));
                    $flags = 2;
                    $peerData[0] = ['tr-peer-'.$trunkid,'account',$data['channelid'],$flags];
                    foreach ($peers as $p){
                        ++$flags;
                        $item = explode("=",trim($p));
                        array_push($peerData,['tr-peer-'.$trunkid,$item[0],$item[1],$flags]);
                    }
                    $this->asterisk_db->createCommand()->batchInsert('sip',['id','keyword','data','flags'],$peerData)->execute();
                }
                //更新sip表reg,删除后再批量写入
                $this->asterisk_db->createCommand()->delete('sip',['id'=>'tr-reg-'.$trunkid])->execute();
                if (trim($data['reg'])){
                    $this->asterisk_db->createCommand()->insert('sip',[
                        'id'        => 'tr-reg-'.$trunkid,
                        'keyword'   => 'register',
                        'data'      => trim($data['reg']),
                        'flags'     => 0
                    ])->execute();
                }
                //更新trunk_dialpatterns表,删除后再批量写入
                $this->asterisk_db->createCommand()->delete('trunk_dialpatterns',['trunkid'=>$trunkid])->execute();
                if (!empty($data['dialpatterns'])){
                    $patternsData = [];
                    foreach ($data['dialpatterns'] as $key=>$d){
                        array_push($patternsData,[$trunkid,$d['match_pattern_prefix'],$d['match_pattern_pass'],$d['prepend_digits'],$key]);
                    }
                    $this->asterisk_db->createCommand()->batchInsert('trunk_dialpatterns',['trunkid','match_pattern_prefix','match_pattern_pass','prepend_digits','seq'],$patternsData)->execute();
                }
                $transaction->commit();
                //必需在提交事务后才重启
                $this->reload();
                return $this->asJson(['code'=>0,'msg'=>'更新中继成功']);
            }catch (\Exception $exception){
                $transaction->rollBack();
                return $this->asJson(['code'=>1,'msg'=>'更新中继失败','data'=>$exception->getMessage(),'d'=>$trunkid]);
            }
        }

        $trunk = (new Query())->from('trunks')->where(['trunkid'=>$trunkid])->one($this->asterisk_db);
        $dialpatterns = (new Query())->from('trunk_dialpatterns')->where(['trunkid'=>$trunkid])->orderBy('seq asc')->all($this->asterisk_db);
        $peers = (new Query())->from('sip')->where(['id'=>'tr-peer-'.$trunkid])->andWhere(['<>','keyword','account'])->orderBy('flags asc')->all($this->asterisk_db);
        $peer_string = '';
        foreach ($peers as $p){
            $peer_string .= $p['keyword'].'='.$p['data']."\n";
        }
        $reg = (new Query())->from('sip')->where(['id'=>'tr-reg-'.$trunkid])->one($this->asterisk_db);
        $reg_string = $reg?$reg['data']:'';
        return $this->render('edit',['trunk'=>$trunk,'dialpatterns'=>$dialpatterns,'peer_string'=>$peer_string,'reg_string'=>$reg_string]);
    }

    /**
     * 删除中继
     * @return \yii\web\Response
     */
    public function actionDestroy()
    {
        $trunkid = Yii::$app->request->post('trunkid');
        $transaction = $this->asterisk_db->beginTransaction();
        try{
            //删除trunks表
            $this->asterisk_db->createCommand()->delete('trunks',['trunkid'=>$trunkid])->execute();
            //删除sip表
            $this->asterisk_db->createCommand()->delete('sip',['in','id',['tr-peer-'.$trunkid,'tr-reg-'.$trunkid]])->execute();
            //删除trunk_dialpatterns表
            $this->asterisk_db->createCommand()->delete('trunk_dialpatterns',['trunkid'=>$trunkid])->execute();
            //删除呼出路由里使用的中继
            $this->asterisk_db->createCommand()->delete('outbound_route_trunks',['trunk_id'=>$trunkid])->execute();
            $transaction->commit();
            //必需在提交事务后才重启
            $this->reload();
            return $this->asJson(['code'=>0,'msg'=>'删除成功']);
        }catch (\Exception $exception){
            $transaction->rollBack();
            return $this->asJson(['code'=>1,'msg'=>'删除失败','data'=>$exception->getMessage()]);
        }
    }

}